<template>
  <div>
    <el-card>
      <!-- 标签表格 -->
      <el-table :data="articleData" style="width: 100%">
        <!-- 多选框 -->

        <el-table-column label="序号">
          <template #default="{ $index }">
            {{ $index + 1 }}
          </template>
        </el-table-column>

        <el-table-column label="文章标题">
          <template #default="{ row }">
            {{ row.title }}
          </template>
        </el-table-column>

        <el-table-column label="文章封面">
          <template #default="{ row }">
            <el-image
              style="width: 100px; height: 100px"
              :src="server_url + row.cover"
              fit="cover"
            />
          </template>
        </el-table-column>

        <el-table-column label="所属分类">
          <template #default="{ row }">
            {{ row.category_name }}
          </template>
        </el-table-column>

        <el-table-column label="所属标签">
          <template #default="{ row }">
            {{ transformTag(tags, row.tag_ids) }}
          </template>
        </el-table-column>

        <el-table-column fixed="right" label="操作" min-width="50">
          <template #default="{ row }">
            <el-button link type="primary" @click="edit(row)">编辑</el-button>
            <el-button link type="primary">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 按钮和分页 -->
      <div class="button">
        <el-button @click="open">添加文章</el-button>
        <el-pagination
          background
          :total="articleCount"
          :page-size="pagesize"
          :current-page="page"
          layout="prev, pager, next, total"
          @current-change="changePage"
        />
      </div>
    </el-card>

    <!-- 标签的表单 -->
    <div class="articleForm" v-if="isShow">
      <el-form :model="newArticleData" ref="articleFormRef">
        <el-form-item label="文章标题" prop="title">
          <el-input v-model="newArticleData.title" />
        </el-form-item>

        <el-form-item label="封面图" prop="imageUrl">
          <el-upload
            class="avatar-uploader"
            :action="uploadUrl"
            :headers="{ Authorization: Storage.get(ACCESS_TOKEN_KEY) }"
            :show-file-list="false"
            name="avatar"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <img v-if="newArticleData.imageUrl" :src="newArticleData.imageUrl" class="avatar" />
            <el-icon v-else class="avatar-uploader-icon">
              <Plus />
            </el-icon>
          </el-upload>
        </el-form-item>

        <el-form-item label="所属分类" prop="category_id">
          <el-select v-model="newArticleData.category_id" placeholder="选择所属的分类">
            <el-option label="请选择" :value="0"></el-option>
            <el-option
              v-for="item in categoryName"
              :key="item.category_id"
              :label="item.category_name"
              :value="item.category_id"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="所属标签" prop="tag_ids">
          <el-select
            v-model="newArticleData.tag_ids"
            multiple
            placeholder="请选择分类标签"
            style="width: 240px"
          >
            <el-option
              v-for="item in tagName"
              :key="item.value"
              :label="item.lable"
              :value="item.value"
            />
          </el-select>
        </el-form-item>

        <!-- markdown内容容器 -->
        <div id="markdown"></div>

        <el-form-item style="margin-top: 10px">
          <el-button type="primary" @click="confirm(articleFormRef)">
            {{ isAdd === "add" ? "添加" : "修改" }}
          </el-button>
          <el-button @click="cancel(articleFormRef)">取消</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script setup lang="ts">
import ArticleAPI, { type ArticleData } from "@/api/system/article.api";
import CategoryAPI, { type CategoryName } from "@/api/system/category.api";
import TagAPI from "@/api/system/tag.api";
import Vditor from "vditor";
import "vditor/dist/index.css";
import { Storage } from "@/utils/storage";
import { ACCESS_TOKEN_KEY } from "@/constants/cache-keys";
import { Plus } from "@element-plus/icons-vue";
import type { UploadProps, FormInstance } from "element-plus";

const page = ref(1);
const pagesize = ref(2);
const articleCount = ref(0);
const articleData = ref<ArticleData[]>(); // 文章的数据
const isShow = ref(false); // 表单的显隐
const newArticleData = ref<ArticleData>({
  article_id: 0,
  title: "",
  content: "",
  tag_ids: [],
  category_id: 0,
  cover: "",
  imageUrl: "",
}); // 新的文章数据
const categoryName = ref<CategoryName[]>(); // 分类名称数据
const tagName = ref(); // 标签名称数据
const tags = ref<any[]>([]);
const vditor = ref<Vditor | null>(null);
const server_url = ref<string>("");
const uploadUrl = ref<string>("http://127.0.0.1:4000/api/admin/upload");
const articleFormRef = ref<FormInstance>(); // 表单校验
const isAdd = ref(""); // 是否为添加

onMounted(() => {
  getArticleData();
  // 获取标签名称数据
  TagAPI.getTagName().then((data) => {
    tags.value = data;
    let tagNameData = data;
    tagName.value = tagNameData.map((item) => {
      let data = { value: item.tag_id, lable: item.tag_name };
      return data;
    });
  });
});

// 编辑
const edit = async (row: ArticleData) => {
  isAdd.value = "edit";
  isShow.value = true;
  // 获取分类名称数据
  categoryName.value = await CategoryAPI.getCategoryName();
  // 获取标签名称数据

  await nextTick();
  initVditor();
  setTimeout(() => {
    // 重置markdown内容
    vditor.value!.setValue("");
  }, 100);
  // 获取所编辑的文章数据
  let result = await ArticleAPI.getEditArticle(row.article_id);
  newArticleData.value = result;
  newArticleData.value.imageUrl = newArticleData.value.cover;
  newArticleData.value.tag_ids = (newArticleData.value.tag_ids as string).split(",").map(Number);
};

// 上传图片成功的回调
const handleAvatarSuccess: UploadProps["onSuccess"] = (response, uploadFile) => {
  // 回显
  newArticleData.value.imageUrl = URL.createObjectURL(uploadFile.raw!);
  // 记录上传成功后的图片路径
  newArticleData.value.cover = response.data.path;
};

// 上传文件的验证规则
const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
  let imgMime = ["image/jpeg", "image/png", "image/gif"];
  if (!imgMime.includes(rawFile.type)) {
    ElMessage.error("图片只能是png、jpg、gif格式");
    return false;
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error("封面图不能超过 2MB!");
    return false;
  }
  return true;
};

// 转换标签函数
const transformTag = (tags: any[], tag_ids: string) => {
  let tag_ids_arr = tag_ids.split(",").map((item) => parseInt(item));
  let newTags: string[] = [];
  tag_ids_arr.forEach((tag_id) => {
    let findTag = tags.find((tag) => tag_id === tag.tag_id);
    if (findTag) {
      newTags.push(findTag.tag_name);
    }
  });
  return newTags.join(",");
};

// 初始化富文本编辑器
const initVditor = () => {
  // 初始化富文本编辑器
  vditor.value = new Vditor("markdown", {
    // height: 400,
    toolbarConfig: {
      hide: false,
      pin: true,
    },
    outline: {
      enable: false,
      position: "right",
    },
    cache: {
      enable: true,
      after(html: string) {
        newArticleData.value.content = html;

        // 固定定位大纲位置
        // let outLineEle = document.querySelector('.vditor-outline')
        // outLineEle.style.position = 'fixed'
        // outLineEle.style.right = '10px'
      },
    },
    upload: {
      url: "http://127.0.0.1:4000/api/admin/upload",
      fieldName: "avatar",
      accept: "image/*",
      // 上传成功的回调
      success(editor: HTMLPreElement, msg: string) {
        let result = JSON.parse(msg);
        let photoUrl = result.data.server_url + result.data.path;
        if (vditor.value) {
          // 插入光标位置
          vditor.value.insertValue(`![](${photoUrl})`);
        }
      },
      headers: {
        // JWT token
        Authorization: Storage.get(ACCESS_TOKEN_KEY),
      },
    },
  });
};

// 取消
const cancel = (formEl: FormInstance | undefined) => {
  formEl!.resetFields();
  isShow.value = false;
};

// 确定
const confirm = async (formEl: FormInstance | undefined) => {
  newArticleData.value.tag_ids = (newArticleData.value.tag_ids as number[]).join(",");
  if (isAdd.value === "add") {
    await ArticleAPI.addArticle(newArticleData.value);
  } else {
    const baseUrl = "http://127.0.0.1:4000/";
    newArticleData.value.cover = newArticleData.value.cover?.replace(baseUrl, "");
    console.log(newArticleData.value);
    await ArticleAPI.changeArticleData(newArticleData.value);
  }
  getArticleData();
  isShow.value = false;
  ElMessage.success("添加文章成功");
  formEl!.resetFields();
};

// 打开表单
const open = async () => {
  isShow.value = true;
  isAdd.value = "add";
  // 获取分类名称数据
  categoryName.value = await CategoryAPI.getCategoryName();
  // 获取标签名称数据

  await nextTick();
  initVditor();
  setTimeout(() => {
    // 重置markdown内容
    vditor.value!.setValue("");
  }, 100);
};

// 获取文章
const getArticleData = async () => {
  let data = await ArticleAPI.getArticle(
    page.value,
    pagesize.value
    // articleData.value.title,
  );
  articleData.value = data.articleData;
  articleCount.value = data.articleCount;
  server_url.value = data.server_url;
};

// 改变页码
const changePage = (newPage: number) => {
  page.value = newPage;
  getArticleData();
};
</script>

<style scoped>
.button {
  display: flex;
  justify-content: space-between;
  width: 100%;
  margin-top: 20px;
}

.articleForm {
  position: fixed;
  top: 0;
  left: 0;
  /* 半透明遮罩 */
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  /* 确保在最上层 */
}

.articleForm .el-form {
  width: 1000px;
  padding: 30px 30px 20px 30px;
  background-color: #fff;
  border-radius: 5px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.avatar-uploader .avatar {
  display: block;
  width: 178px;
  height: 178px;
}

.avatar-uploader .el-upload {
  position: relative;
  overflow: hidden;
  cursor: pointer;
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  width: 100px;
  height: 100px;
  font-size: 28px;
  color: #8c939d;
  text-align: center;
}
</style>
